package com.util;

import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.*;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 阿里云oss封装工具类
 *
 * @Author: 黑白奥利奥
 * @Date: 2019/11/5 8:49
 * @Version 1.0
 */
@SuppressWarnings("all")
public final class OSSUtils {
    private volatile static OSSClient ossClient = null;

    private static final String ENDPOINT = PropertiesUtil.getProperty("aliyun.bucket.endpoint");
    private static final String ACCESS_KEY_ID = PropertiesUtil.getProperty("aliyun.access_key");
    private static final String ACCESS_KEY_SECRET = PropertiesUtil.getProperty("aliyun.accessKey_secret");
    private static final String BUCKET_NAME = PropertiesUtil.getProperty("aliyun.bucketName");

    private OSSUtils() {
    }

    private static OSSClient getOssClient() {
        if (ossClient == null) {
            synchronized (OSSUtils.class) {
                if (ossClient == null) {
                    ossClient = new OSSClient(ENDPOINT, ACCESS_KEY_ID, ACCESS_KEY_SECRET);
                }
            }
        }
        return ossClient;
    }

    public static void main(String[] args) throws IOException {
        String url = uploadFile(new File("D:\\图片\\edge-images\\440923197211100827.jpg"), "product/", "440923197211100827.jpg");
        System.out.println("url = " + url);

        String pathUrl = getPathUrl(url);
        System.out.println("pathUrl = " + pathUrl);
    }

    /**
     * 上传资源到OSS服务器,
     *
     * @param inputStream 资源输入流
     * @param fileDir     要存储的文件夹名称
     * @param fileUrl     文件路径 + 文件名称
     * @return
     */
    public static String uploadFile(InputStream inputStream, String fileDir, String fileUrl) throws IOException {
        String dotSuffix = fileUrl.substring(fileUrl.lastIndexOf("."));
        ObjectMetadata objectMetadata = new ObjectMetadata();
        objectMetadata.setContentLength(inputStream.available());
        objectMetadata.setCacheControl("no-cache");
        objectMetadata.setHeader("Pragma", "no-cache");
        objectMetadata.setContentType(OSSUtils.getContentType(dotSuffix));
        objectMetadata.setContentDisposition("inline;filename=" + System.currentTimeMillis() + dotSuffix);
        PutObjectResult putObjectResult = OSSUtils.getOssClient().putObject(BUCKET_NAME, fileDir + fileUrl, inputStream, objectMetadata);
        return fileDir + fileUrl;
    }

    /**
     * 获取路径地址
     *
     * @param fileUrl 文件路径
     * @return
     */
    public static String getPathUrl(String fileUrl) {
        return fileUrl.indexOf("/") == 0 ? fileUrl.substring(1) : fileUrl;
    }

    /**
     * 通过文件名判断并获取OSS服务文件上传时文件的contentType
     *
     * @param dotSuffix 点 + 加后缀
     * @return 文件的contentType
     */
    private static String getContentType(String dotSuffix) {
        //文件的后缀名

        if (".bmp".equalsIgnoreCase(dotSuffix)) {
            return "image/bmp";
        }
        if (".gif".equalsIgnoreCase(dotSuffix)) {
            return "image/gif";
        }
        if (".jpeg".equalsIgnoreCase(dotSuffix) || ".jpg".equalsIgnoreCase(dotSuffix) || ".png".equalsIgnoreCase(dotSuffix)) {
            return "image/jpeg";
        }
        if (".html".equalsIgnoreCase(dotSuffix)) {
            return "text/html";
        }
        if (".txt".equalsIgnoreCase(dotSuffix)) {
            return "text/plain";
        }
        if (".vsd".equalsIgnoreCase(dotSuffix)) {
            return "application/vnd.visio";
        }
        if (".ppt".equalsIgnoreCase(dotSuffix) || "pptx".equalsIgnoreCase(dotSuffix)) {
            return "application/vnd.ms-powerpoint";
        }
        if (".doc".equalsIgnoreCase(dotSuffix) || "docx".equalsIgnoreCase(dotSuffix)) {
            return "application/msword";
        }
        if (".xml".equalsIgnoreCase(dotSuffix)) {
            return "text/xml";
        }
        if (".pdf".equals(dotSuffix)) {
            return "application/pdf";
        }
        if (".avi".equals(dotSuffix) || ".mpg".equals(dotSuffix) || ".mpeg".equals(dotSuffix) || ".mp4".equals(dotSuffix)) {
            return "video/*";
        }
        if (".mp3".equals(dotSuffix) || ".wav".equals(dotSuffix)) {
            return "audio/*";
        }
        //默认返回类型
        return "image/jpeg";
    }

    /**
     * File格式 文件上传
     *
     * @param fileDir bucket下的祖父级文件夹
     * @param fileUrl 保存的路径
     * @param file    文件实体
     * @return
     */
    public static String uploadFile(File file, String fileDir, String fileUrl) throws IOException {
        InputStream inputStream = new FileInputStream(file);
        return OSSUtils.uploadFile(inputStream, fileDir, fileUrl);
    }

    /**
     * MultipartFile格式 文件上传
     *
     * @param fileDir bucket下的祖父级文件夹
     * @param fileUrl 保存的路径
     * @param file    文件实体
     * @return
     */
    public static String uploadFile(MultipartFile file, String fileDir, String fileUrl) throws IOException {
        InputStream inputStream = file.getInputStream();
        return OSSUtils.uploadFile(inputStream, fileDir, fileUrl);
    }

    /**
     * 删除oss资源文件
     *
     * @param fileNameList 文件路径集合 /顶级文件名称/*
     */
    public static void deleteFile(List<String> fileNameList) {
        if (!CollectionUtils.isEmpty(fileNameList)) {
            List<String> newKeys = fileNameList.stream().map(OSSUtils::getPathUrl).collect(Collectors.toList());
            DeleteObjectsResult deleteObjectsResult = OSSUtils.getOssClient().deleteObjects(new DeleteObjectsRequest(BUCKET_NAME).withKeys(newKeys));
            List<String> deletedObjects = deleteObjectsResult.getDeletedObjects();
        }
    }

    /**
     * 删除单个文件资源
     *
     * @param fileName 资源文件路径 /顶级文件名称/*
     */
    public static void deleteFile(String fileName) {
        List<String> keys = new ArrayList<>();
        keys.add(fileName);
        deleteFile(keys);
    }

    /**
     * 根据文件路径获取文件输入流
     *
     * @param bucketName
     * @param fileUrl    资源文件路径
     * @return
     */
    public static InputStream getOSSInputStream(String bucketName, String fileUrl) {
        OSSObject ossObj = OSSUtils.getOssClient().getObject(bucketName, getPathUrl(fileUrl));
        return ossObj.getObjectContent();
    }

}
